home *** CD-ROM | disk | FTP | other *** search
/ Apple Developer Connection 1998 Fall: Game Toolkit / Disc.iso / SDKs / PCI Driver Development Kit / • Tools / Utility / LogLibrary 950622 / Src / DumpLog.c next >
Encoding:
C/C++ Source or Header  |  1996-08-20  |  10.7 KB  |  506 lines  |  [TEXT/MPCC]

  1. /*                                        DumpLog.c                                    */
  2. /*
  3.  * DumpLog.c
  4.  * Copyright © 1992-95 Apple Computer Inc. All Rights Reserved.
  5.  *
  6.  * Edit History
  7.  */
  8. #include "DumpLog.h"
  9. #include <stdio.h>
  10.  
  11. #ifndef TRUE
  12. #define TRUE    1
  13. #define FALSE    0
  14. #endif
  15.  
  16. enum {
  17.     NUL            = 0,
  18.     kOpenQuote    = 0xD2,
  19.     kCloseQuote    = 0xD3
  20. };
  21. #define kLogLinkFailed            ((UniversalProcPtr) (-1L))
  22.  
  23. void                        DoAllLogRecords(void);
  24. void                        DoThisLogRecord(
  25.         LogRecordPtr            logRecordPtr
  26.     );
  27. void                        DoLogEntryRange(
  28.         LogRecordPtr            logRecordPtr,
  29.         UInt32                    startIndex,
  30.         UInt32                    endIndex
  31.     );
  32. void                        ConvertTimestamp(
  33.         LogEntryPtr                logEntryPtr,
  34.         DateTimeRec                *eventDateTime,
  35.         UInt32                    *residualNanoseconds
  36.     );
  37.  
  38.  
  39. #define AppendChar(result, theChar)    do {                \
  40.         StringPtr        _dst = (result);                \
  41.         _dst[++_dst[0] & 0xFF] = theChar;                \
  42.     } while (0)
  43. void                        PutUnsignedLeadingZeros(
  44.         UInt32                    value,
  45.         short                    digits,
  46.         unsigned char            terminator
  47.     );
  48. void                        PutHexLeadingZeros(
  49.         UInt32                    value,
  50.         short                    digits
  51.     );
  52. void                        PutUnsigned(
  53.         UInt32                    value
  54.     );
  55. void                        PutSigned(
  56.         SInt32                    value
  57.     );
  58. void                        PutUnsignedInField(
  59.         UInt32                    value,
  60.         short                    fieldWidth
  61.     );
  62. void                        PutChar(
  63.         unsigned char            datum
  64.     );
  65. void                        PutPascalString(
  66.         ConstStr255Param        datum
  67.     );
  68. void                        PutCString(
  69.         const char                *datum
  70.     );
  71. void                        PutLine(void);
  72.  
  73. LogRecordPtr                FindLogRecordPtr(
  74.         StringPtr                logRecordName            /* Log name (P-string)        */
  75.     );
  76.  
  77. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  78.  * WriteAllLogRecords
  79.  *
  80.  * Enumerate the Log Record entries and dump any new information.
  81.  */
  82. void
  83. WriteAllLogRecords(void)
  84. {
  85.         OSErr                    status;
  86.          LogRecordIter            cookie;
  87.         LogRecordPtr            logRecordPtr;
  88.  
  89.         /*
  90.          * Second pass does the work.
  91.          */        
  92.         status = LogRecordIterateCreate(&cookie);
  93.         if (status == noErr) {
  94.             while ((logRecordPtr = LogRecordIterate(&cookie)) != NULL)
  95.                 WriteThisLogRecord(logRecordPtr);
  96.             LogRecordIterateDispose(&cookie);
  97.         }
  98.  
  99. }
  100.  
  101. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  102.  * WriteThisLogRecord
  103.  *
  104.  * Enumerate the Log Record entries and dump any new information.
  105.  */
  106. void
  107. WriteThisLogRecord(
  108.         LogRecordPtr            logRecordPtr
  109.     )
  110. {
  111.         LogEntryRecord            thisLogEntry;
  112.         static LogRecordPtr        lastLogRecordPtr;
  113.         short                    limitCount;
  114.  
  115.         limitCount = 0;
  116.         while (ReadLogEntry(logRecordPtr, &thisLogEntry) == noErr) {
  117.             if (lastLogRecordPtr != logRecordPtr) {
  118.                 PutPascalString("\p ");
  119.                 PutCString((const char *) logRecordPtr->logName);
  120.                 PutLine();
  121.                 lastLogRecordPtr = logRecordPtr;
  122.             }
  123.             DoThisLogEntry(&thisLogEntry);
  124.             if (++limitCount >= 512 || Button())     /* Always process events        */
  125.                 break;
  126.         }
  127. }            
  128.  
  129. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  130.  * DoAllLogRecords
  131.  *
  132.  * Enumerate through the Log Record entries in the Name Registry.
  133.  */
  134. void
  135. DoAllLogRecords(void)
  136. {
  137.         OSErr                    status;
  138.          LogRecordIter            cookie;
  139.         LogRecordPtr            logRecordPtr;
  140.         UInt32                    count;
  141.  
  142.         /*
  143.          * First pass just lists the records.
  144.          */
  145.         status = LogRecordIterateCreate(&cookie);
  146.         count = 0;
  147.         while ((logRecordPtr = LogRecordIterate(&cookie)) != NULL) {
  148.             ++count;
  149.             PutPascalString("\p ");
  150.             PutCString((const char *) logRecordPtr->logName);
  151.             PutPascalString("\p at ");
  152.             PutHexLeadingZeros((UInt32) logRecordPtr, 8);
  153.             PutLine();
  154.         }
  155.         LogRecordIterateDispose(&cookie);
  156.         PutUnsigned(count);
  157.         PutPascalString(
  158.             (count == 1) ? "\p LogRecord found" : "\p LogRecords found"
  159.         );
  160.         PutLine();
  161.         /*
  162.          * Second pass does the work.
  163.          */        
  164.         status = LogRecordIterateCreate(&cookie);
  165.         if (status == noErr) {
  166.             while ((logRecordPtr = LogRecordIterate(&cookie)) != NULL)
  167.                 DoThisLogRecord(logRecordPtr);
  168.             LogRecordIterateDispose(&cookie);
  169.         }
  170. }
  171.  
  172. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  173.  * DoThisLogRecord
  174.  *
  175.  * We have a LogRecord. Fetch a copy of the static part of the record, display the
  176.  * fixed information, then display all LogEntries.
  177.  */
  178. void
  179. DoThisLogRecord(
  180.         LogRecordPtr            logRecordPtr
  181.     )
  182. {
  183.         LogRecord                logRecordCopy;
  184.         OSErr                    status;
  185. #define LOG (logRecordCopy)
  186.  
  187.         if (logRecordPtr != NULL) {
  188.             PutPascalString("\p• LogRecord \"");
  189.             PutCString((const char *) logRecordPtr->logName);
  190.             PutPascalString("\p\", at ");
  191.             PutHexLeadingZeros((UInt32) logRecordPtr, 8);
  192.             PutLine();
  193.             status = CopyLogRecordInfo(logRecordPtr, &logRecordCopy);
  194.             if (status != noErr) {
  195.                 PutPascalString("\pCould not copy log record: ");
  196.                 PutSigned(status);
  197.                 PutLine();
  198.             }
  199.             else {
  200.                 if (LOG.semaphore != 0) {
  201.                     PutPascalString("\p  ••• Semaphore locked •••\n");
  202.                     PutLine();
  203.                 }
  204.                 if (LOG.lostLockCounter != 0) {
  205.                     PutPascalString("\p  Lost Semaphore Counter ");
  206.                     PutUnsigned(LOG.lostLockCounter);
  207.                     PutLine();
  208.                 }
  209.                 PutPascalString("\p  Sequence Counter ");
  210.                 PutUnsigned(LOG.sequenceCounter);
  211.                 PutPascalString("\p, Flags = "); 
  212.                 PutHexLeadingZeros(LOG.flags, 8);
  213.                 PutPascalString("\p, ");
  214.                 PutPascalString(
  215.                     ((LOG.flags & kLogDataEnabledMask) != 0)
  216.                         ? "\pEnabled"
  217.                         : "\pDisabled"
  218.                 );
  219.                 PutPascalString("\p, Preserve ");
  220.                 PutPascalString(
  221.                     ((LOG.flags & kLogDataPreserveFirstMask) != 0)
  222.                         ? "\pearliest."
  223.                         : "\pmost recent."
  224.                 );
  225.                 PutLine();
  226.                 if ((LOG.flags & kLogDataWrapAroundMask) != 0) {
  227.                     if (LOG.entryGetIndex < LOG.entryPutIndex) {
  228.                         /*
  229.                          * +------------+
  230.                          * |            |
  231.                          * | Get Index    |    Do Put+1 to End (already displayed)
  232.                          * |            |    Do Start to Get (already displayed)
  233.                          * | Put Index    |    Do Get+1 to Put (yet to be displayed)
  234.                          * |            |
  235.                          * +------------+
  236.                          */
  237.                         DoLogEntryRange(            /* Already displayed            */
  238.                             logRecordPtr,
  239.                             LOG.entryPutIndex + 1,
  240.                             LOG.entryMaxIndex - 1
  241.                         );
  242.                         DoLogEntryRange(            /* Already displayed            */
  243.                             logRecordPtr,
  244.                             0,
  245.                             LOG.entryGetIndex
  246.                         );
  247.                         DoLogEntryRange(            /* Not yet displayed            */
  248.                             logRecordPtr,
  249.                             LOG.entryGetIndex + 1,
  250.                             LOG.entryPutIndex
  251.                         );
  252.                     }
  253.                     else {
  254.                         /*
  255.                          * +------------+
  256.                          * |            |
  257.                          * | Put Index    |    Do Put+1 to Get (already displayed)
  258.                          * |            |    Do Get+1 to End (yet to be displayed)
  259.                          * | Get Index    |    Do Start to Put (yet to be displayed)
  260.                          * |            |
  261.                          * +------------+
  262.                          */
  263.                         DoLogEntryRange(            /* Already displayed            */
  264.                             logRecordPtr,
  265.                             LOG.entryPutIndex + 1,
  266.                             LOG.entryGetIndex
  267.                         );
  268.                         DoLogEntryRange(            /* Not yet displayed            */
  269.                             logRecordPtr,
  270.                             LOG.entryGetIndex + 1,
  271.                             LOG.entryMaxIndex - 1
  272.                         );
  273.                         DoLogEntryRange(            /* Not yet displayed            */
  274.                             logRecordPtr,
  275.                             0,
  276.                             LOG.entryPutIndex
  277.                         );
  278.                     }
  279.                 }
  280.                 else {
  281.                     /*
  282.                      * We haven't wrapped around yet.
  283.                      * +------------+
  284.                      * | 0            |    Untouched
  285.                      * | 1            |    First real entry
  286.                      * |            |
  287.                      * | Get Index    |
  288.                      * |            |    Do Start to Get (already displayed)
  289.                      * | Put Index    |    Do Get+1 to Put (yet to be displayed)
  290.                      * |            |
  291.                      * +------------+
  292.                      */
  293.                      DoLogEntryRange(                /* Already displayed            */
  294.                         logRecordPtr,
  295.                         1,
  296.                         LOG.entryGetIndex
  297.                     );
  298.                     DoLogEntryRange(                /* Not yet displayed            */
  299.                         logRecordPtr,
  300.                         LOG.entryGetIndex + 1,
  301.                         LOG.entryPutIndex
  302.                     );
  303.                 }
  304.                 PutPascalString("\p• End of \"");
  305.                 PutCString((const char *) &LOG.logName);
  306.                 PutPascalString("\p\"");
  307.                 PutLine();
  308.             }
  309.         }
  310. }
  311.  
  312. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  313.  * DoLogEntryRange
  314.  *
  315.  * Process a range of log record entries. Note: the range is inclusive
  316.  */
  317. void
  318. DoLogEntryRange(
  319.         LogRecordPtr            logRecordPtr,
  320.         UInt32                    startIndex,
  321.         UInt32                    endIndex
  322.     )
  323. {
  324.         LogEntryRecord            thisLogEntry;
  325.         OSErr                    status;
  326.  
  327.         while (startIndex <= endIndex) {
  328.             status = CopyLogEntry(
  329.                         logRecordPtr, startIndex, &thisLogEntry);
  330.             if (status == noErr)
  331.                 DoThisLogEntry(&thisLogEntry);
  332.             else if (status == fBsyErr) {
  333.                 PutPascalString("\p Semaphore Locked");
  334.                 PutLine();
  335.                 break;
  336.             }
  337.             else {
  338.                 PutSigned(status);
  339.                 PutPascalString("\p: strange status");
  340.                 PutLine();
  341.                 break;
  342.             }
  343.             ++startIndex;
  344.         }
  345. }
  346.  
  347.  
  348. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  349.  * DoThisLogEntry
  350.  *
  351.  * Display a single log entry.
  352.  */
  353. void
  354. DoThisLogEntry(
  355.         LogEntryPtr                logEntryPtr
  356.     )
  357. {
  358.         DateTimeRec                eventDateTime;
  359.         UInt32                    residualNanoseconds;
  360.         Str255                    work;
  361. #define ENTRY (*logEntryPtr)
  362.  
  363.         /*
  364.          * This is what we've been waiting for. We compute the timestamp
  365.          * using a native-only algorithm to get better accuracy than we
  366.          * could get using the 68000-compatible algorithm.
  367.          */
  368.         LogConvertTimestamp(logEntryPtr, &eventDateTime, &residualNanoseconds);
  369.         PutUnsignedInField(ENTRY.sequence, 5);
  370.         PutPascalString("\p ");
  371.         PutUnsignedLeadingZeros(eventDateTime.hour,                2, ':');
  372.         PutUnsignedLeadingZeros(eventDateTime.minute,            2, ':');
  373.         PutUnsignedLeadingZeros(eventDateTime.second,            2, '.');
  374.         PutUnsignedLeadingZeros(residualNanoseconds / 1000L,    6, NUL); /* uSec    */
  375.         FormatLogEntryData(&ENTRY, work);
  376.         PutPascalString("\p ");
  377.         PutPascalString(work);
  378.         PutLine();
  379. #undef ENTRY
  380. }
  381.  
  382. /*
  383.  * Output an n-digit value with leading zeros.
  384.  */
  385. void
  386. PutUnsignedLeadingZeros(
  387.         UInt32                    value,
  388.         short                    digits,
  389.         unsigned char            terminator
  390.     )
  391. {
  392.         if (--digits > 0)
  393.             PutUnsignedLeadingZeros(value / 10, digits, NUL);
  394.         PutChar((value % 10) + '0');
  395.         if (terminator != NUL)
  396.             PutChar(terminator);
  397. }
  398.  
  399. /*
  400.  * Output a signed decimal longword.
  401.  */
  402. void
  403. PutSigned(
  404.         SInt32                    value
  405.     )
  406. {
  407.         if (value < 0) {
  408.             PutChar('-');
  409.             value = (-value);
  410.         }
  411.         PutUnsigned((unsigned long) value);
  412. }
  413.  
  414. /*
  415.  * Output an unsigned decimal longword.
  416.  */
  417. void
  418. PutUnsigned(
  419.         UInt32                    value
  420.     )
  421. {
  422.         if (value >= 10)
  423.             PutUnsigned(value / 10);
  424.         PutChar((value % 10) + '0');
  425. }
  426.  
  427. /*
  428.  * Output a string of hex digits with leading zeros.
  429.  */
  430. void
  431. PutHexLeadingZeros(
  432.         unsigned long            value,
  433.         short                    digits
  434.     )
  435. {
  436.         if (--digits > 0)
  437.             PutHexLeadingZeros(value >> 4, digits);
  438.         value &= 0x0F;
  439.         PutChar((value < 10)
  440.                 ? value + '0'
  441.                 : (value + ('A' - 10))
  442.             );
  443. }
  444.  
  445. /*
  446.  * Output an n-digit decimal value with leading blanks.
  447.  */
  448. void
  449. PutUnsignedInField(
  450.         UInt32                    value,
  451.         short                    fieldWidth
  452.     )
  453. {
  454.         Str15                    work;
  455.         
  456.         NumToString(value, work);
  457.         while (work[0] < fieldWidth) {
  458.             PutChar(' ');
  459.             --fieldWidth;
  460.         }
  461.         PutPascalString(work);
  462. }
  463.  
  464. void
  465. PutPascalString(
  466.         ConstStr255Param        datum
  467.     )
  468. {
  469.         DumpDrawString(datum);
  470. }
  471.  
  472. void
  473. PutCString(
  474.         const char                *datum
  475.     )
  476. {
  477.         char                    *cp;
  478.         
  479.         for (cp = (char *) datum; *cp != NUL; cp++)
  480.             PutChar(*cp);
  481. }                
  482.  
  483. void
  484. PutChar(
  485.         unsigned char            datum
  486.     )
  487. {
  488.         char            work[1];
  489.         
  490.         if (datum == '\n')
  491.             PutLine();
  492.         else {
  493.             work[0] = datum;
  494.             DumpDrawText((const char *) &work[0], sizeof (char));
  495.         }
  496. }
  497.  
  498.  
  499. void
  500. PutLine(void)
  501. {
  502.         DumpDrawLine("\p");
  503. }
  504.  
  505.  
  506.